﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using System.Web;
using System.Web.Mvc;
using System.Text;

using Common.Model;
using Common.Error;
using OpenAPI.Model.OAuth;
using OpenAPI.BLL.OAuth;
using OpenAPI.Web.Mvc.Helper;
using OpenAPI.Web.Mvc.Filter;

namespace OpenAPI.Web.Mvc.Controllers
{
    public class APIController : Controller
    {

        public ActionResult Index()
        {
            return View();
        }

        #region REST

        [HttpGet]
        public ActionResult Rest()
        {
            string xml = "";

            string api_method = Utility.StringHelper.GetRequest("api_method");  //Request.QueryString["api_method"].ToString();
            xml = this.ExecuteRest(api_method);

            ViewData["XML"] = xml;

            return View();
        }

        [HttpPost]
        [ActionName("Rest")]
        public ActionResult PostRest()
        {
            string xml = "";

            string api_method = Utility.StringHelper.GetRequest("api_method");  //Request.Form["api_method"].ToString();
            xml = this.ExecuteRest(api_method);

            ViewData["XML"] = xml;

            return View();
        }

        /// <summary>
        /// 获取失败XML
        /// </summary>
        /// <param name="method"></param>
        /// <returns></returns>
        private string GetDefaultFailureXML(string method, string err_msg)
        {
            StringBuilder xml = new StringBuilder();

            xml.AppendLine("<?xml version=\"1.0\" encoding=\"utf-8\" ?> ");
            xml.AppendLine("<rsp method=\"" + method + "\" flag=\"false\" code=\"\"  desc=\"" + err_msg + "\" >");
            xml.AppendLine("<data />");
            xml.AppendLine("</rsp>");

            return xml.ToString();
        }

        /// <summary>
        /// 获取签名验证失败XML
        /// </summary>
        /// <param name="method"></param>
        /// <returns></returns>
        private string GetValidateFailureXML(string method, ErrorType error)
        {
            StringBuilder xml = new StringBuilder();

            xml.AppendLine("<?xml version=\"1.0\" encoding=\"utf-8\" ?> ");
            xml.AppendLine("<rsp method=\"" + method + "\" flag=\"false\" code=\"\"  desc=\"" + ((error == null) ? "Invalid signature" : error.ERROR_MESSAGE) + "\" >");
            xml.AppendLine("<data />");
            xml.AppendLine("</rsp>");

            return xml.ToString();
        }

        /// <summary>
        /// 获取Token验证失败XML
        /// </summary>
        /// <param name="method"></param>
        /// <returns></returns>
        private string GetChkOAuthFailureXML(string method)
        {
            StringBuilder xml = new StringBuilder();

            xml.AppendLine("<?xml version=\"1.0\" encoding=\"utf-8\" ?> ");
            xml.AppendLine("<rsp method=\"" + method + "\" flag=\"false\" code=\"\"  desc=\"Invalid oauth token/secret\" >");
            xml.AppendLine("<data />");
            xml.AppendLine("</rsp>");

            return xml.ToString();
        }

        /// <summary>
        /// 获取执行方法失败XML
        /// </summary>
        /// <param name="method"></param>
        /// <returns></returns>
        private string GetExecuteMethodFailureXML(string method)
        {
            StringBuilder xml = new StringBuilder();

            xml.AppendLine("<?xml version=\"1.0\" encoding=\"utf-8\" ?> ");
            xml.AppendLine("<rsp method=\"" + method + "\" flag=\"false\" code=\"\"  desc=\"Can't execute this method\" >");
            xml.AppendLine("<data />");
            xml.AppendLine("</rsp>");

            return xml.ToString();
        }


        /// <summary>
        /// 执行API方法
        /// </summary>
        /// <param name="method"></param>
        /// <returns></returns>
        private string ExecuteRest(string method)
        {
            string xml = "";
            ResultInfo result = new ResultInfo();
            ErrorType error = null;

            try
            {
                string api_signature = Utility.StringHelper.GetRequest("api_signature");

                if (!APIHelper.ValidateSignature(method, api_signature, out error))
                {
                    xml = this.GetValidateFailureXML(method, error);
                }
                else if (!OpenAPI.BLL.OAuth.ConsumerManager.ContainsMethodInConsumerLevel(Utility.StringHelper.GetRequest("oauth_consumer_key"), method))
                {
                    xml = this.GetExecuteMethodFailureXML(method);
                }
                else
                {

                    //执行API方法
                    switch (method.ToLower().Trim())
                    {
                        #region OAuth类API
                        case "openapi.oauth.requesttoken":
                            xml = APIHelper.ExecuteAPIMethod(method);
                            break;
                        case "openapi.oauth.authorizetoken":
                            xml = APIHelper.ExecuteAPIMethod(method);
                            break;
                        #endregion
                        default:
                            // 检测Token是否合法
                            string oauth_consumer_key = Utility.StringHelper.GetRequest("oauth_consumer_key");
                            string oauth_token = Utility.StringHelper.GetRequest("oauth_token");

                            if (!OpenAPI.BLL.OAuth.ConsumerManager.ChkOAuthToken(oauth_consumer_key, oauth_token))
                            {
                                xml = this.GetChkOAuthFailureXML(method);
                            }
                            else
                            {
                                xml = APIHelper.ExecuteAPIMethod(method);
                            }
                            break;
                    }
                }
            }
            catch (Exception ex)
            {
                xml = this.GetDefaultFailureXML(method, ex.Message);
            }

            return xml.ToString();
        }

        #endregion

        #region 测试器

        [HttpGet]
        [ConsumerAuthFilter]
        public ActionResult Test()
        {
            ViewData["API_URL"] = System.Configuration.ConfigurationManager.AppSettings["API_URL"].ToString();
            ViewData["SELECTED_METHOD"] = "";
            ViewData["API_METHOD"] = new SelectList(APIHelper.GetMethods("", ""), "Value", "Text", ViewData["SELECTED_METHOD"].ToString());
            ViewData["API_SECRET_ARGUMENT"] = null;
            ViewData["UnSignArgumets"] = null;
            ViewData["SignArgumets"] = null;

            ViewData["URL"] = "";

            return View();
        }

        [HttpPost]
        [ConsumerAuthFilter]
        [ActionName("Test")]
        public ActionResult DoTest()
        {
            string api_url = Utility.StringHelper.GetPost("txtAPI_URL");
            string selected_method = Request.Form["ddlAPI_METHOD"].ToString();//Utility.StringHelper.GetPost("ddlAPI_METHOD");

            ViewData["API_URL"] = api_url;
            ViewData["SELECTED_METHOD"] = selected_method;
            ViewData["API_METHOD"] = new SelectList(APIHelper.GetMethods("", ""), "Value", "Text", selected_method);
            ViewData["API_SECRET_ARGUMENT"] = this.GetAPISecretArgument(selected_method);
            ViewData["UnSignArgumets"] = this.InitUnSignArguments(selected_method);
            ViewData["SignArgumets"] = APIHelper.GetSignArguments(selected_method);

            ViewData["URL"] = this.GetUrl(selected_method);
            return View();
        }

        [HttpGet]
        [ConsumerAuthFilter]
        public ActionResult PostTest()
        {
            string api_method = "";

            ViewData["SELECTED_METHOD"] = "";
            ViewData["API_METHOD"] = new SelectList(APIHelper.GetMethods("", ""), "Value", "Text", api_method);
            ViewData["API_SECRET_ARGUMENT"] = null;
            ViewData["UnSignArgumets"] = null;
            ViewData["SignArgumets"] = null;

            ViewData["API_SIGNATURE"] = "";

            return View();
        }

        [HttpPost]
        [ConsumerAuthFilter]
        [ActionName("PostTest")]
        public ActionResult DoPostTest()
        {
            string api_method = Request.Form["ddlAPI_METHOD"].ToString();

            ViewData["SELECTED_METHOD"] = api_method;
            ViewData["API_METHOD"] = new SelectList(APIHelper.GetMethods("", ""), "Value", "Text", api_method);
            ViewData["API_SECRET_ARGUMENT"] = this.GetAPISecretArgument(api_method);
            ViewData["UnSignArgumets"] = this.InitUnSignArguments(api_method);
            ViewData["SignArgumets"] = APIHelper.GetRequestSignArguments(api_method);

            ViewData["API_SIGNATURE"] = APIHelper.GetSignature(api_method, (ArrayList)ViewData["SignArgumets"], ((ArgumentInfo)ViewData["API_SECRET_ARGUMENT"]).Value);

            return View();
        }


        [HttpPost]
        [ConsumerAuthFilter]
        public ActionResult AjaxSubmitRequest()
        {
            ResultInfo result = new ResultInfo();

            string request_url = Request.Form["request_url"].ToString();

            if (string.IsNullOrEmpty(request_url))
            {
                result.FLAG = false;
                result.CODE = "";
                result.DESC = "请求URL不能空";
                result.DATA = null;
            }
            else
            {
                //远程请求令牌
                XElement rsp = XElement.Load(request_url);

                result.FLAG = bool.Parse(rsp.Attribute("flag").Value);
                result.CODE = rsp.Attribute("code").Value;
                result.DESC = rsp.ToString();
                result.DATA = null;
            }

            return Json(result, JsonRequestBehavior.AllowGet);
        }



        /// <summary>
        /// 合成URL
        /// </summary>
        /// <param name="method"></param>
        /// <returns></returns>
        private string GetUrl(string method)
        {
            string url = "";

            ArrayList unSignArguments = APIHelper.GetUnSignArguments(method);
            ArrayList arguments = APIHelper.GetSignArguments(method);

            foreach (ArgumentInfo argument in unSignArguments)
            {
                argument.Value = Utility.StringHelper.GetPost(argument.Name);
            }

            foreach (ArgumentInfo argument in arguments)
            {
                argument.Value = Utility.StringHelper.GetPost(argument.Name);
            }

            url = APIHelper.GetUrl(method, unSignArguments, arguments, Utility.StringHelper.GetPost("txtAPI_SECRET"));

            return url;
        }


        /// <summary>
        /// 初始化未签名参数
        /// </summary>
        /// <param name="method"></param>
        /// <returns></returns>
        private ArrayList InitUnSignArguments(string method)
        {
            ArrayList unSignArguments = APIHelper.GetUnSignArguments(method);

            foreach (ArgumentInfo argument in unSignArguments)
            {
                if (argument.Name == "oauth_consumer_key")
                {
                    argument.Value = Session["USER_ID"].ToString();
                }
                else
                {
                    argument.Value = (string.IsNullOrEmpty(Utility.StringHelper.GetPost(argument.Name)) ? "" : Utility.StringHelper.GetPost(argument.Name));
                }
            }

            return unSignArguments;
        }


        /// <summary>
        /// 获取API调用密钥
        /// </summary>
        /// <param name="method"></param>
        /// <returns></returns>
        private ArgumentInfo GetAPISecretArgument(string method)
        {
            ArgumentInfo argument = null;
            string secret_key = APIHelper.GetSignSecretKey(method);

            if (secret_key == "oauth_consumer_key")
            {
                argument = new ArgumentInfo("oauth_consumer_secret", Session["PASSWORD"].ToString());
            }
            else if (secret_key == "oauth_token")
            {
                argument = new ArgumentInfo("oauth_token_secret", (string.IsNullOrEmpty(Utility.StringHelper.GetPost("txtAPI_SECRET")) ? "" : Utility.StringHelper.GetPost("txtAPI_SECRET")));
            }
            else
            {
                argument = null;
            }

            return argument;
        }


        #endregion


    }
}
